package com.neusoft.databus.common.connection;

import java.util.Map;

import com.neusoft.bizcore.web.utils.JsonUtils;
import com.neusoft.databus.common.constant.DatabusConstant;
import com.neusoft.databus.common.enums.PhysicalConnType;
import com.neusoft.databus.common.exception.ConfigErrorException;

/**
 * 连接工厂
 *
 * @author sunchf
 * @date 2019年1月7日 下午1:51:01
 */
public class ConnectionFactory {
    /**
     * 根据网关连接类型和配置，创建网关连接对象.
     *
     * @param connType 网关连接类型
     * @param connectionInfo 网关连接配置
     * @return 网关连接对象
     * @exception 找不到采集器、扩展协议找不到具体实现或配置不正确会向上抛出ConfigErrorException异常
     */
    @SuppressWarnings("unchecked")
    public static AbstractConnection createConnectionInfo(final PhysicalConnType connType,
            final String connectionInfo) {
        AbstractConnection connection = null;
        switch (connType) {
        case SOCKET:
        case SOCKET2:
        case NETTY:
            connection = JsonUtils.jsonToPojo(connectionInfo, SocketConnection.class);
            break;
        case SNMP:
            connection = JsonUtils.jsonToPojo(connectionInfo, SnmpConnection.class);
            break;
        case SERIAL:
            connection = JsonUtils.jsonToPojo(connectionInfo, SerialConnection.class);
            break;
        case OPC:
            connection = JsonUtils.jsonToPojo(connectionInfo, OpcConnection.class);
            break;
        case PLUGIN:
            final Map<String, Object> connectionInfoMap = JsonUtils.jsonToMap(connectionInfo);
            if ((null == connectionInfoMap) || !connectionInfoMap.containsKey("connName")) {
                throw new ConfigErrorException("使用自定义的数据采集插件，但网关未配置连接名称");
            }
            final String connName = (String) connectionInfoMap.get("connName");
            final StringBuilder sb = new StringBuilder();
            sb.append(DatabusConstant.PACKAGE_PREFIX_CONNECTION_CLASS)
                    .append(connName.substring(0, 1).toUpperCase())
                    .append(connName.substring(1, connName.length()).toLowerCase()).append("Connection");
            try {
                final Class<AbstractConnection> clazz = (Class<AbstractConnection>) Class.forName(sb.toString());
                connection = JsonUtils.jsonToPojo(connectionInfo, clazz);
            } catch (final ClassNotFoundException e) {
                throw new ConfigErrorException("使用自定义的数据采集插件，但系统未找到指定的插件", e);
            } catch (final Exception e) {
                throw new ConfigErrorException("使用自定义的数据采集插件，JSON转换时出错", e);
            }
            break;
        default:
            throw new ConfigErrorException("不支持的数据采集协议");
        }

        return connection;
    }
}
